/***************************************
 *
 * Fractal Mountain Generator
 * Author: Evan Salazar
 * February 2008
 * 
 ***************************************/
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include "povparser/povparser.h"
#include "povparser/POVObject.h"
#include <vector>
#include "grass.h"
#include <QThread>
#include "../sceneelems/sky.h"
#include "../sceneelems/ground.h"
#include "../geom/Octree.h"
#include "../geom/Triangle.h"
#include "../glutil/ModelRenderer.h"
#include "../glutil/FBO.h"
#include "../glutil/shaderUtils.h"
#include "../glutil/EffectsPass.h"
#include "AOProgressDialog.h"
#include <QGLWidget>

class aoThread : public QThread
{
	Q_OBJECT
	private:
		POVGeom::POVObject * m_obj;
		Octree<Triangle> * m_octree;
		int m_numRays;
		AOProgressDialog * progress;
	public:
		aoThread(POVGeom::POVObject * object, Octree<Triangle> * oct, int numRays, AOProgressDialog * prog) : m_obj(object), m_octree(oct), m_numRays(numRays), progress(prog){}
		void run()	{m_obj->generateAO(m_octree,m_numRays,progress);}
};

/** GLWidget*/
class GLWidget : public QGLWidget
{
    Q_OBJECT

    public:
        GLWidget(QWidget *parent = 0);
        ~GLWidget();

    public slots:
        void showChooseOpenModelDialog();   
        void selectedFileChanged(int numFile);
        void removeFile(int numFile);
		void generateAOForSelectedModel();
		void setOctreeResolution(int res);
		void setAOQuality(int q);
		void setExposure(double exposure);
		void setGamma(double gamma);
		void setContrast(double contrast);
		void setBrightness(double brightness);
		void setBloomLevels(int levels);
		void setBloomDistance(double distance);
		void setBloomMean(double mean);
		void setBloomAmount(double amount);

		void changeTreeColor(string partName, QColor color);
		void showSaveFileDialog();
		void showOpenFileDialog();

    signals:
        void newTreeModelFileOpened(QString s);
        void noFileSelected();
		void clearColorsList();
		void clearFilesList();
		void addColorToList(string name, QColor color);
    protected:
        void setCamera();
        void set2DCamera();
        void initializeGL();
        void paintGL();
		void update3DModel();
        void setGLLight();
        void resizeGL(int width, int height);
        void mousePressEvent(QMouseEvent *event);
        void mouseMoveEvent(QMouseEvent *event);
        void wheelEvent(QWheelEvent * event);
        void keyPressEvent ( QKeyEvent * event );

        QString showOpenModelDialog();

    private:
        int widgetWidth;
        int widgetHeight;
        float camDist;
        float rotx;
        float roty;
        QPoint lastPos;
        std::vector<POVGeom::POVObject *> trees;

		auto_ptr<glutil::ModelRenderer> m_renderer;
        int selectedTree;
        Ground  * ground;
		Grass * grass;

		sceneelems::Sky m_sky;

		float skyBrightness;
        GLuint groundTexture;
        GLuint groundTexture2;
        float lightAngle;
		int m_octreeRes;
		int m_AOQuality;
		glutil::FBO m_mainFBO;
		glutil::FBO m_hblurFBO; // also used for rays
		glutil::FBO m_vblurFBO;

		glutil::ShaderProgram * m_bloomShader;
		glutil::ShaderProgram * m_hblurShader;
		glutil::ShaderProgram * m_vblurShader;
		glutil::ShaderProgram * m_raysShader;
		glutil::ShaderProgram * m_mainShader;
		glutil::ShaderProgram * m_skyShader;

		glutil::EffectsPass * m_raysPass;
		glutil::EffectsPass * m_hblurPass;
		glutil::EffectsPass * m_vblurPass;
		glutil::EffectsPass * m_finalPass;
};

#endif /*GLWIDGET_H*/

